package mithrilwings.ship.controller;

import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import fifis.base.controller.BController;
import fifis.game.common.Common;
import java.util.ArrayList;
import java.util.Collection;
import mithrilwings.constants.Constants;
import mithrilwings.game.MainMithrilWings;
import mithrilwings.ship.model.ShipModel;
import mithrilwings.ship.view.ShipView;
import org.apache.log4j.Logger;

/**
 *
 * @author porfiriopartida
 */
public final class ShipController extends BController {
    final static protected Logger log4j = Logger.getLogger(ShipController.class);
    static final long serialVersionUID = 1L;
    public static Vector3f start = Vector3f.ZERO;
    
    public ShipController(String name, int maxHp, int attack, int defense) {
        ShipModel model = new ShipModel(name, maxHp, attack, defense);
        setModel(model);
        setView(new ShipView(model));
        count++;
        getNode().setLocalScale(.8f);
//        setLocalTranslation(start);
        resetPosition();
    }

    public ShipController(String name) {
        this(name, 100, 10, 10);
    }
    static int count = 0;

    public ShipController() {
        this("Ship_" + (++count));
    }
    Vector3f walkDirection = new Vector3f();
    @Override
    public void update() {
        if(MainMithrilWings.me != this || MainMithrilWings.me == null){
            return;
        }
        walkDirection.set(0, 0, 0);
        walkDirection.addLocal(Common.getInstance().getCamera().getDirection());
        player.setWalkDirection(walkDirection);
        player.setViewDirection(walkDirection);
        if(ghostControl!=null){
            ghostControl.setPhysicsRotation(getNode().getLocalRotation());
        }
        Collection<ParticleEmitter> safeCollection = detachUs.subList(0, detachUs.size());
        try {
            for (ParticleEmitter s : safeCollection) {
                try {
                    s.setEnabled(false);
                    s.setParticlesPerSec(0);
                    s.removeFromParent();
                    detachUs.remove(s);
                } catch (Exception e) {
                    log4j.error("ShipController detachUs " + e.getMessage());
                    continue;
                }
            }
        } catch (Exception e) {
        }
        /**
         * This could cause a bug:
         *   Adding a explotion just before this line will not call removeFromParent because it's not in the list to remove it.
         *    Will add collided() to test the bug.
         * 
         * Uncomment this to test the bug
         *  if(removing)
         *      collided();
         */
        
//        detachUs.removeAll(safeCollection);
//        detachUs.clear();
    }

    public Vector3f getDirection() {
        if(player!=null)
            return player.getViewDirection();
        else
            return Common.getInstance().getCamera().getDirection();
    }
    ArrayList<ParticleEmitter> detachUs = new ArrayList<ParticleEmitter>();
    boolean readyToCollision = true;

    public void collided() {
        if (!readyToCollision) {
            return;
        }

        readyToCollision = false;


        final ParticleEmitter explosion = debris.clone();
//        final ParticleEmitter explosion = getExplosion();
        explosion.setLocalTranslation(getNode().getLocalTranslation());
        Common.getInstance().getRootNode().attachChild(explosion);
        explosion.emitAllParticles();
//        setLocalTranslation(start);
        resetPosition();

        readyToCollision = true;

        new Thread() {

            @Override
            public void run() {
                try {
                    Thread.sleep(6000);
                } catch (Exception ex) {
                } finally {
                    detachUs.add(explosion);
                }
            }
        }.start();
    }
    public static ParticleEmitter debris;

//    public ParticleEmitter getExplosion() {
//        ParticleEmitter debris;
//        debris = new ParticleEmitter("Debris", ParticleMesh.Type.Triangle, 10);
//        debris.setMaterial(debris_mat);
//        debris.setImagesX(3);
//        debris.setImagesY(3); // 3x3 texture animation
//        debris.setRotateSpeed(4);
//        debris.setSelectRandomImage(true);
//        debris.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 4, 0));
//        debris.setStartColor(new ColorRGBA(1f, 1f, 1f, 1f));
//        debris.setGravity(0f, 6f, 0f);
//        debris.getParticleInfluencer().setVelocityVariation(.60f);
//        debris.setLowLife(2f);
//        debris.setHighLife(.1f);
//        return debris;
//    }
//    static Material debris_mat;

    public static void initMaterials() {
        /** Explosion effect. Uses Texture from jme3-test-data library! */
        debris = new ParticleEmitter("Debris", ParticleMesh.Type.Triangle, 10);
        Material debris_mat = new Material(Common.getInstance().getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
        debris_mat.setTexture("m_Texture", Common.getInstance().getAssetManager().loadTexture("Effects/Explosion/Debris.png"));
        debris.setMaterial(debris_mat);
        debris.setImagesX(3);
        debris.setImagesY(4); // 3x3 texture animation
        debris.setRotateSpeed(4);
        debris.setSelectRandomImage(true);
        debris.getParticleInfluencer().setInitialVelocity(new Vector3f(2, 30, 5));
        debris.setStartColor(new ColorRGBA(1f, 1f, 1f, 1f));
        debris.setGravity(1f, 6f, 2f);
        debris.getParticleInfluencer().setVelocityVariation(.20f);
        debris.setLowLife(.2f);
        debris.setHighLife(1f);
    }

    @Override
    public CollisionShape getRigidCollisionShape() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
//    CapsuleCollisionShape shape;

    @Override
    public CollisionShape getGhostCollisionShape() {
//        return new BoxCollisionShape(Vector3f.UNIT_XYZ);
        return new CapsuleCollisionShape(2.2f,3.2f);
//        return shape;
    }
    @Override
    public CollisionShape getCharacterCollisionShape() {
        if (shape != null) {
            return shape;
        } else {
//        return new BoxCollisionShape(Vector3f.UNIT_XYZ);
//            shape = new CapsuleCollisionShape(3, 2);
            shape = new BoxCollisionShape(Vector3f.UNIT_XYZ);
//            shape = CollisionShapeFactory.createDynamicMeshShape(getNode());
        }
//        CollisionShape sceneShape =
//                new CapsuleCollisionShape(2, 3);
        return shape;
//        return new CapsuleCollisionShape(2, 3);
//        return new BoxCollisionShape(Vector3f.ZERO);
//        return new CapsuleCollisionShape(3, 2);
    }

    public String getLocationRotation() {
        String transform = "";
        Vector3f location = getNode().getLocalTranslation();
        Vector3f rotation = player.getViewDirection();
        
        transform += Constants.UPDATE_LOCATION_ROTATION;
        transform += " ";
        transform += location.x;
        transform += " ";
        transform += location.y;
        transform += " ";
        transform += location.z;
        transform += " ";
        transform += rotation.x;
        transform += " ";
        transform += rotation.y;
        transform += " ";
        transform += rotation.z;
        
        return transform;
    }
//    public void setLocationRotation(String transform) {
////        String transform = "";
//        String[] args = transform.split(" ");
//        
//        Vector3f location = player.getPhysicsLocation();
//        Vector3f viewDirection = player.getViewDirection();
//        
//        transform += Constants.UPDATE_LOCATION_ROTATION;
//        transform += " ";
//        transform += location.x;
//        transform += " ";
//        transform += location.y;
//        transform += " ";
//        transform += location.z;
//        transform += " ";
//        transform += viewDirection.x;
//        transform += " ";
//        transform += viewDirection.y;
//        transform += " ";
//        transform += viewDirection.z;
////        return transform;
//    }
//    public void setLocationRotation(float[] transform) {
////        String transform = "";
//        Vector3f location = new Vector3f(transform[0], transform[1], transform[2]);
//        Vector3f viewDirection = new Vector3f(transform[3], transform[4], transform[5]);
//        player.setPhysicsLocation(location);
//        player.setViewDirection(viewDirection);
//    }
    public void setLocationRotation(Vector3f location, Vector3f viewDirection) {
//        String transform = "";
//        Vector3f location = new Vector3f(transform[0], transform[1], transform[2]);
//        Vector3f viewDirection = new Vector3f(transform[3], transform[4], transform[5]);
        player.setPhysicsLocation(location);
        player.setViewDirection(viewDirection);
    }

    @Override
    public boolean isAlive() {
        return true;
    }

    public void resetPosition() {
        setLocalTranslation(start);
    }
}
